//
//  DPObjC-Compatibility.m
//  HigherOrderMessaging
//
//  Created by Ofri Wolfus on 28/10/06.
//  Copyright 2006 Ofri Wolfus. All rights reserved.
//

#import "DPObjC-Compatibility.h"

#if !__OBJC2__

char *method_copyReturnType(Method m) {
	char	*type = method_getTypeEncoding(m);
	int		i, l = strlen(type);
	char	*r;
	
	//Skip type qualifiers
	while (*type == _C_CONST
		   || *type == _C_IN
		   || *type == _C_INOUT
		   || *type == _C_OUT
		   || *type == _C_BYCOPY
		   || *type == _C_BYREF
		   || *type == _C_ONEWAY)
    {
		type += 1;
    }
	
	//Find the offset of the return type. When we reach it, we found what we looked for.
	for (i = 0; i < l; i++) {
		switch (type[i]) {
			case '0' ... '9':
				r = malloc(sizeof(char) * (i == 1 ? 2 : i));
				strncpy(r, type, i);
				r[i] = '\0';
				return r;
				
			default:
				break;
		}
	}
	
	return NULL;
}

char *method_copyArgumentType(Method m, unsigned int index) {
	char *s, *r;
	size_t l;
	int i;
	
	method_getArgumentInfo(m, index, (const char **)&s, NULL);
	l = strlen(s);
	
	for (i = 0; i < l; i++) {
		switch (s[i]) {
			case '0' ... '9':
				r = malloc(sizeof(char) * (i == 1 ? 2 : i));
				strncpy(r, s, i);
				r[i] = '\0';
				return r;
				
			default:
				break;
		}
	}
	
	return NULL;
}

void method_getReturnType(Method m, char *dst, size_t dst_len) {
	size_t l, len = strlen(m->method_types);
	
	for (l = 0; l < len; l++) {
		switch (m->method_types[l]) {
			case '0' ... '9':
				break;
			default:
				continue;
		}
	}
	
	strncpy(dst, m->method_types, MIN(l, dst_len));
}

void method_getArgumentType(Method m, unsigned int index,
							char *dst, size_t dst_len)
{
	char *s;
	size_t l, len;
	
	method_getArgumentInfo(m, index, (const char **)&s, NULL);
	len = strlen(s);
	
	for (l = 0; l < len; l++) {
		switch (s[l]) {
			case '0' ... '9':
				break;
			default:
				continue;
		}
	}
	
	strncpy(dst, s, MIN(l, dst_len));
}

BOOL class_respondsToSelector(Class cls, SEL sel) {
	return (class_getClassMethod(cls, sel) ?: class_getInstanceMethod(cls, sel)) != NULL;
}

#endif
